﻿using IterationLife.Datas;
using IterationLife.System.ExternalIdentity;
using IterationLife.System.Models;
using IterationLife.System.Services;
using Util.Exceptions;

namespace IterationLife.Mobile.AppServices.Services.System.Implements
{
    class AuthenticationService : IAuthenticationService
    {
        private readonly IApplicationUnitOfWork _unitOfWork;
        private readonly IUserManager _userManager;
        private readonly ISignInManager _signInManager;

        public AuthenticationService(IApplicationUnitOfWork unitOfWork, IUserManager userManager, ISignInManager signInManager)
        {
            _unitOfWork = unitOfWork;
            _userManager = userManager;
            _signInManager = signInManager;
        }

        public string ExternalLogin(string provider, string authorizationCode, string accessToken)
        {
            IExternalUserProvider userProvider = ExternalUserProviderFactory.CreateExternalUserProvider(provider);
            ExternalUserInfo userInfo;
            if (authorizationCode != null)
                userInfo = userProvider.GetUserInfoByAuthorizationCode(authorizationCode);
            else if (accessToken != null)
                userInfo = userProvider.GetUserInfoByAccessToken(accessToken);
            else
                throw new Warning("错误的认证凭据");

            var user = _userManager.FindUserByExternalLogin(provider, userInfo.ExternalUserId);
            if (user == null)
            {
                _userManager.CreateUserByUserInfo(provider, userInfo);
            }

            var result = _signInManager.ExternalLoginSignIn(provider, userInfo.ExternalUserId);
            VerifySignInResult(result);
            return result.Token;
        }

        public string Login(string account, string password)
        {
            var result = _signInManager.PasswordSignIn(account, password);
            VerifySignInResult(result);
            return result.Token;
        }

        private static void VerifySignInResult(SignInResult result)
        {
            if (!result.Succeeded)
                throw new Warning("用户名或密码错误");
            if (result.IsLockedOut)
                throw new Warning("账号被锁定");
            if (result.IsNotAllowed)
                throw new Warning("账号被禁用");
        }

        public string Register(string username, string password, string phone = null, string verifyCode = null)
        {
            var user = _userManager.Register(username, password, phone, verifyCode);
            _unitOfWork.Commit();
            SignInResult result = _signInManager.SignIn(user);
            VerifySignInResult(result);
            return result.Token;
        }

        public void SendRegisterCode(string phone)
        {
            _userManager.SendRegisterCode(phone);
            _unitOfWork.Commit();
        }

        public void SendGetBackPasswordCode(string phone)
        {
            _userManager.SendGetBackPasswordCode(phone);
            _unitOfWork.Commit();
        }

        public void GetBackPassword(string phone, string newPassword, string verifyCode)
        {
            _userManager.GetBackPassword(phone, newPassword, verifyCode);
            _unitOfWork.Commit();
        }
    }
}
